const { src, dest, series, parallel, watch } = require('gulp');
const path = require('path')

const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()

const del = require('del')
const bs = require('browser-sync')

const cwd = process.cwd()

/*
  引入配置文件，并覆盖默认配置
 */
let config = {}
const defaultConfig = {
  // default config
  data: {},
  build: {
    src: 'src',
    dist: 'dist',
    temp: 'temp',
    public: 'public',
  },
  dev: {
    port: 3000
  }
}

try {
  const loadConfig = require(`${cwd}/simple.conf.js`)
  config = Object.assign({}, defaultConfig, loadConfig)
} catch (error) {
  
}


const data = config.data
const buildconfig = config.build
const devconfig = config.dev


/*
  定义目录及glob
 */
const dist = path.join(cwd, buildconfig.dist)
const temp = path.join(cwd, buildconfig.temp)
const home = path.join(cwd, buildconfig.src)

const styles = path.join(home, 'assets/**/*.scss')
const scripts = path.join(home, 'assets/**/*.js')
const pages = path.join(home, '*.html')
const images = path.join(home, 'assets/images/**')
const fonts = path.join(home, 'assets/fonts/**')
const public = path.join(cwd, `${buildconfig.public}/**`)


/* 
  定义task
 */
const style = () => {
  return src(styles, { base: home })
    .pipe(plugins.sass({outputStyle: 'expanded'}))
    .pipe(dest(temp))
    .pipe(bs.reload({stream: true}))
}

const script = () => {
  return src(scripts, {base: home})
    .pipe(plugins.babel({presets: [require('@babel/preset-env')]}))
    .pipe(dest(temp))
    .pipe(bs.reload({stream: true}))
}

const image = () => {
  return src(images, {base: home})
    .pipe(plugins.imagemin())
    .pipe(dest(dist))
}

const font = () => {
  return src(fonts, {base: home})
    .pipe(plugins.imagemin())
    .pipe(dest(dist))
}

const page = () => {
  return src(pages, {base: home})
    .pipe(plugins.swig({data, defaults: {cache: false}}))
    .pipe(dest(temp))
    .pipe(bs.reload({stream: true}))
}


const copy = () => {
  return src(public, {base: cwd})
    .pipe(dest(dist))
}

const serve = () => {
  watch('assets/styles/**', {cwd: home}, style)
  watch('*.html', {cwd: home}, page)
  watch('assets/scripts/**', {cwd: home}, script)

  watch(['assets/fonts/**', 'assets/images/**'], {cwd: home}, bs.reload)
  watch('**', {cwd: public}, bs.reload)

  bs.init({
    open: true,
    // files: [`${home}/**/*.scss`, `${home}/*.html`, `${home}/**/*.js`],
    // files: `${temp}/**`,
    port: devconfig.port,
    server: {
      baseDir: [temp, home, public],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

const useref = () => {
  return src(`${temp}/*.html`, { base: 'temp' })
    .pipe(plugins.useref({ searchPath: [buildconfig.temp/* searchPath是相对路径，决定路径会忽略 */, '.'] }))
    // html js css
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    })))
    .pipe(dest('dist'))
}

const compile = parallel(style, script, page)


const clean = () => {
  return del([dist, temp])
}

const dev = series(compile, serve)

const build =series(clean, parallel(copy, image, font, series(compile, useref)))

module.exports = {
  dev,
  build,
  clean,
}